上一章節講了 Animated 的使用
我們運用 start() 來做個骨架屏唷!
import { Animated } from 'react-native';
thumbnailAnimated = new Animated.Value(0); // 骨架屏的初始值
imageAnimated = new Animated.Value(0); // 真正banner的初始值
// 骨架屏
<Animated.Image
    {...props}
    source={thumbnailSource}
    style={[style, { opacity: this.thumbnailAnimated }]}
    onLoad={this.handleThumbnailLoad}
    blurRadius={1}
/>
// banner
<Animated.Image
    {...props}
    source={source}
    style={[styles.imageOverlay, { opacity: this.imageAnimated }]}
    onLoad={this.onImageLoad}
/>
// 骨架屏
handleThumbnailLoad = () => {
    Animated.timing(this.thumbnailAnimated, {
    toValue: 1
    }).start();
};
// banner
onImageLoad = () => {
    Animated.timing(this.imageAnimated, {
    toValue: 1,
    duration: 1000
    }).start();
};
    <ProgressiveImage
        thumbnailSource={require('../asset/version-1.png')} // 骨架屏圖片
        source={img} // banner
        style={styles.bannerImg}
        resizeMode="cover"
        text="文字文字"
    />
import React from 'react';
import { View, Animated, StyleSheet, Text } from 'react-native';
class ProgressiveImage extends React.Component {
    thumbnailAnimated = new Animated.Value(0);
    imageAnimated = new Animated.Value(0);
    handleThumbnailLoad = () => {
        Animated.timing(this.thumbnailAnimated, {
        toValue: 1
        }).start();
    };
    onImageLoad = () => {
        Animated.timing(this.imageAnimated, {
        toValue: 1,
        duration: 1000
        }).start();
    };
    render() {
        const { thumbnailSource, source, style, ...props } = this.props;
        return (
            <View style={styles.container}>
                <Animated.Image
                    {...props}
                    source={thumbnailSource}
                    style={[style, { opacity: this.thumbnailAnimated }]}
                    style={style}
                    onLoad={this.handleThumbnailLoad}
                    blurRadius={1}
                />
                <Animated.Image
                    {...props}
                    source={source}
                    style={[styles.imageOverlay, { opacity: this.imageAnimated }]}
                    onLoad={this.onImageLoad}
                />
                <Text style={[styles.bannerText, { lineHeight: 0 }]}>
                    {props.text}
                </Text>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    imageOverlay: {
        position: 'absolute',
        left: 0,
        right: 0,
        bottom: 0,
        top: 0
    },
    container: {
        backgroundColor: '#e1e4e8'
    },
    bannerText: {
        color: "#fff",
        position: 'absolute',
        left: 15,
        bottom: 100
    }
});
export default ProgressiveImage;
運用 animated 的特性將圖片讀取後慢慢淡出,倘若沒有讀取成功,就會由骨架屏來顯示!!
倘若骨架屏不想有圖片只想有背景色
可忽略所有有包含 thumbnail 文字的 func or 變數
他會取 container 的背景顏色來當預設
Day18 done,請多多指教~